"""
@author:王耀
@date:2021/9/17
"""

import numpy as np
import cv2

def getGaussKernal(size, sigma, center):
    """
    作用：获得高斯滤波核
    size(int): kernal的大小
    sigma(double): 方差
    center(int): size // 2

    返回(numpy.array)：高斯滤波kernal
    """
    # 根据高斯函数计算滤波核
    # 首先初始化滤波和kernel，然后两层循环带入高斯函数进行计算
    kernel = np.zeros((size, size), dtype=np.float)
    for i in range(-center, -center + size):
        for j in range(-center, -center + size):
            kernel[j + center, i + center] = np.exp(-(i ** 2 + j ** 2) / (2 * (sigma ** 2)))

    kernel = kernel / (2 * np.pi * sigma ** 2)

    # 归一化
    kernel = kernel / kernel.sum()

    return kernel



def GaussFilter(img, size = 3, sigma = 0.01):
    """
    作用：高斯滤波核心代码
    img：输入的图片
    size(int)：滤波大小
    sigma(double)：高斯函数方差

    返回：滤波后的图片
    """
    if img is None:
        raise Exception('input image ERROR!')

    if len(img.shape) == 2:
        H, W = img.shape
        C = 0   # 如果输入的已经是灰度图，那么将C = 0，便于后面算法中将彩色图和灰度图分开
    else:
        H, W, C = img.shape  # 加入了对彩色图的处理

    if sigma <= 0 or size <= 0:
        raise Exception('sigma and kernel size should bigger than 0')

    center = size // 2
    kernal = getGaussKernal(size, sigma, center)

    if C == 0: #灰度图处理方式
        res = np.zeros((H + center * 2, W + center * 2), dtype=np.float)  #res比img在外面多了center圈
    else: #彩色图处理方式
        res = np.zeros((H + center * 2, W + center * 2, C), dtype=np.float)

    res[center: center + H, center: center + W] = img.copy().astype(np.float)

    restmp = res.copy()

    # 逐像素进行滤波，彩色图多一层循环
    if C == 0: #灰度图处理方式
        for h in range(H):
            for w in range(W):
                res[center + h, center + w] = np.sum(kernal * restmp[h: h + size, w: w + size])
    else: #彩色图处理方式
        for h in range(H):
            for w in range(W):
                for c in range(C):
                    res[center + h, center + w, c] = np.sum(kernal * restmp[h: h + size, w: w + size, c])

    res = np.clip(res, 0, 255)
    res = res[center: center + H, center: center + W].astype(np.uint8)

    print('执行完毕：高斯滤波')
    return res


######################################
# if __name__ == '__main__':
#     img = cv2.imread('test.jpg')
#     cv2.imshow('yuantu', img)
#     cv2.waitKey()
#     img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#     result_img = GaussFilter(img, 3, 1)
#     cv2.imshow('高斯滤波后', result_img)
#     cv2.waitKey()